# @Time : 2024/12/20 23:12
# @Author : Fioman 
# @Phone : 13149920693
"""
文件路径帮助类
"""
import os
import shutil
from datetime import datetime

import cv2 as cv

import app_config
from common.datetime_helper import get_date_only, get_datetime_for_filename
from common.exception_helper import error_handler_produce
from common.produce_logger import debug_produce
from personal_tool.data_result import DataResult


def get_filename_without_extension(fullPath: str) -> str:
    """
    根据文件的全路径获取文件的不带扩展名的文件名
    @param fullPath: 文件路径
    @return:
    """
    return os.path.splitext(os.path.basename(fullPath))[0]


def remove_old_dirs_by_name(root_dir, days_threshold=7):
    """
    根据目录名中的日期清理旧目录
    :param root_dir: 根目录路径（如 D:\raw）
    :param days_threshold: 保留天数阈值（默认7天）
    """
    try:
        now = datetime.now()
        # 遍历根目录下所有子目录
        for dir_name in os.listdir(root_dir):
            dir_path = os.path.join(root_dir, dir_name)
            if not os.path.isdir(dir_path):
                continue  # 跳过非目录

            # 尝试解析目录名为日期（格式：YYYY-MM-DD）
            try:
                dir_date = datetime.strptime(dir_name, "%Y-%m-%d")
            except ValueError:
                continue  # 忽略不符合格式的目录

            # 计算日期差
            delta = now - dir_date
            if delta.days > days_threshold:
                try:
                    shutil.rmtree(dir_path)
                    debug_produce(f"已删除旧目录: {dir_path}")
                except Exception as e:
                    debug_produce(f"删除目录失败: {dir_path}, 错误: {str(e)}")
    except Exception as e:
        debug_produce(f"清理旧目录时发生错误: {str(e)}")


def create_dir_by_order(orderId):
    """
    根据工单Id和拼接的层数,去初始化当前作业的图像目录
    """
    dirList = []
    rootDir = r"D:\raw"
    remove_old_dirs_by_name(rootDir)
    rootDir = os.path.join(rootDir, r"{}\{}".format(
        get_date_only(), orderId))

    app_config.firstCutDir = os.path.join(rootDir, r"firstCut")
    dirList.append(app_config.firstCutDir)
    app_config.sizeCheckOkDir = os.path.join(rootDir, r"firstCut\sizeCheckOk")
    dirList.append(app_config.sizeCheckOkDir)

    app_config.rawOkDir = os.path.join(rootDir, r"rawOk")
    dirList.append(app_config.rawOkDir)

    app_config.rawCutDir = os.path.join(rootDir, r"rawCut")
    dirList.append(app_config.rawCutDir)

    app_config.rawFailDir = os.path.join(rootDir, r"rawFail")
    dirList.append(app_config.rawFailDir)

    app_config.totalboardErrorDir = os.path.join(rootDir, r"totalboardError")
    dirList.append(app_config.totalboardErrorDir)

    for dir in dirList:
        try:
            if not os.path.exists(dir):
                os.makedirs(dir)
        except Exception as e:
            debug_produce(str(e))


@error_handler_produce
def save_joint_image(image):
    """
    保存拼接图像
    :param image:
    :return:
    """
    fileName = f"{get_datetime_for_filename()}.bmp"
    fileSavePath = os.path.join(app_config.imageJointDir, fileName)
    if image is not None:
        cv.imwrite(fileSavePath, image)
    else:
        debug_produce("in save_joint_image() error: image is None")


def delete_exist_index_image(keepDir, boardIndex):
    """
    遍历保存图像的目录,删除将要保存的相同id的图片
    :param keepDir:图片保存目录
    :param boardIndex:图像id序列号
    :return:
    """
    for root, dirs, files in os.walk(keepDir):
        for file in files:
            # 只删除当前目录下的,如果有多级目录,会误删除
            if root != keepDir:
                continue
            try:
                index = file.split('--')[0]
                if index == str(boardIndex):
                    os.remove(os.path.join(root, file))
            except Exception as e:
                print(str(e))


def open_dir(dirName: str) -> DataResult:
    """
    打开目录
    :param dirName:
    :return:
    """
    ret = os.system(f"explorer.exe {dirName}")
    if ret == 1:
        return DataResult(state=True)
    else:
        return DataResult(info="目录打开失败,请确认目录是否存在")


def save_totalboard_error_image(index, image, imageRes) -> DataResult:
    """
    保存物料区域识别失败的图像
    """
    try:
        keepDir = app_config.totalboardErrorDir

        delete_exist_index_image(keepDir, index)
        fileNameOriginal = f"{index}--{get_datetime_for_filename()}--original.bmp"
        fileNameRes = f"{index}--{get_datetime_for_filename()}--res.bmp"
        if imageRes is not None:
            cv.imwrite(os.path.join(keepDir, fileNameOriginal), image)
        if imageRes is not None:
            cv.imwrite(os.path.join(keepDir, fileNameRes), imageRes)
    except Exception as e:
        debug_produce(f"in save_size_is_ok_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)


def save_size_is_ok_image(index, image, width, height, endwith="calc") -> DataResult:
    try:
        keepDir = app_config.sizeCheckOkDir
        delete_exist_index_image(keepDir, index)
        fileName = f"{index}--{get_datetime_for_filename()}--w_{width}--h_{height}--{endwith}.bmp"
        cv.imwrite(os.path.join(keepDir, fileName), image)
    except Exception as e:
        debug_produce(f"in save_size_is_ok_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)


def save_calc_error_image(index, image, width, height):
    """
    保存识别失败的图像
    :param index:
    :param image:
    :param width:
    :param height:
    :param jointNumber:
    :return:
    """
    try:
        keepDir = app_config.rawFailDir
        delete_exist_index_image(keepDir, index)
        fileName = f"{index}--{get_datetime_for_filename()}--w_{width}--h_{height}.bmp"
        cv.imwrite(os.path.join(keepDir, fileName), image)
    except Exception as e:
        debug_produce(f"in save_calc_error_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)


def save_calc_ok_image(index, image, width, height):
    try:
        keepDir = app_config.rawOkDir
        delete_exist_index_image(keepDir, index)
        fileName = f"{index}--{get_datetime_for_filename()}--w_{width}--h_{height}.bmp"
        cv.imwrite(os.path.join(keepDir, fileName), image)
    except Exception as e:
        debug_produce(f"in save_calc_ok_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)


def save_cut_line_image(index, image, width, height, endwith="calc"):
    try:
        keepDir = app_config.rawCutDir
        delete_exist_index_image(keepDir, index)
        fileName = f"{index}--{get_datetime_for_filename()}--w_{width}--h_{height}--{endwith}.bmp"
        cv.imwrite(os.path.join(keepDir, fileName), image)
    except Exception as e:
        debug_produce(f"in save_cut_line_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)


def save_first_cutline_image(index, image, width, height, endwith="calc") -> DataResult:
    try:
        keepDir = app_config.firstCutDir
        delete_exist_index_image(keepDir, index)
        fileName = f"{index}--{get_datetime_for_filename()}--w_{width}--h_{height}--{endwith}.bmp"
        cv.imwrite(os.path.join(keepDir, fileName), image)
    except Exception as e:
        debug_produce(f"in save_first_cutline_image() error: {str(e)}")
        return DataResult(state=False)
    return DataResult(state=True)
